/** * Plugin Name: Auto SEO Meta * Description: Автогенерация SEO meta через Groq API. Multi-geo. * Version: 1.0 */ if (!defined('ABSPATH')) exit; if (!defined('AUTO_SEO_GROQ_KEY')) define('AUTO_SEO_GROQ_KEY', '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'); if (!defined('AUTO_SEO_MODEL')) define('AUTO_SEO_MODEL', 'llama-3.3-70b-versatile'); if (!defined('AUTO_SEO_PLUGIN')) define('AUTO_SEO_PLUGIN', 'yoast'); if (!defined('AUTO_SEO_LANG')) define('AUTO_SEO_LANG', 'English'); if (!function_exists('auto_seo_meta_keys')) { add_action('save_post', 'auto_seo_on_save', 20, 3); function auto_seo_meta_keys() { $map = [ 'rankmath' => ['title' => 'rank_math_title', 'desc' => 'rank_math_description'], 'yoast' => ['title' => '_yoast_wpseo_title', 'desc' => '_yoast_wpseo_metadesc'], 'seopress' => ['title' => '_seopress_titles_title', 'desc' => '_seopress_titles_desc'], 'aioseo' => ['title' => '_aioseo_title', 'desc' => '_aioseo_description'], ]; return $map[AUTO_SEO_PLUGIN] ?? $map['rankmath']; } function auto_seo_on_save($post_id, $post, $update) { if (wp_is_post_revision($post_id) || wp_is_post_autosave($post_id)) return; if ($post->post_status !== 'publish') return; if (!in_array($post->post_type, ['post', 'page'])) return; $keys = auto_seo_meta_keys(); $existing_t = get_post_meta($post_id, $keys['title'], true); $existing_d = get_post_meta($post_id, $keys['desc'], true); if (!empty($existing_t) && !empty($existing_d)) return; $seo = auto_seo_generate($post); if (!$seo) return; if (empty($existing_t)) update_post_meta($post_id, $keys['title'], $seo['title']); if (empty($existing_d)) update_post_meta($post_id, $keys['desc'], $seo['description']); } function auto_seo_generate($post) { $title = $post->post_title; $content = wp_strip_all_tags($post->post_content); $content = mb_substr($content, 0, 3000); if (empty($content) && empty($title)) return false; $site_name = get_bloginfo('name'); $site_desc = get_bloginfo('description'); $domain = parse_url(home_url(), PHP_URL_HOST); $lang = AUTO_SEO_LANG; $prompt = "You are an SEO expert. Generate SEO meta title (max 60 chars) and description (max 155 chars) for this webpage.\n\n"; $prompt .= "Output language: {$lang}\n"; $prompt .= "Site: {$site_name} ({$domain})\n"; if ($site_desc) $prompt .= "Site tagline: {$site_desc}\n"; $prompt .= "\nPage title: {$title}\n\n"; $prompt .= "Content:\n{$content}\n\n"; $prompt .= "Rules:\n- Title max 60 chars, includes main keyword\n- Description max 155 chars, compelling\n- Output in {$lang} only\n- No quotes\n- Output ONLY valid JSON:\n"; $prompt .= '{"title":"...","description":"..."}'; $response = wp_remote_post('https://api.groq.com/openai/v1/chat/completions', [ 'timeout' => 30, 'headers' => [ 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . AUTO_SEO_GROQ_KEY, ], 'body' => json_encode([ 'model' => AUTO_SEO_MODEL, 'messages' => [['role' => 'user', 'content' => $prompt]], 'temperature' => 0.7, 'max_tokens' => 300, 'response_format' => ['type' => 'json_object'], ]) ]); if (is_wp_error($response)) { error_log('Auto SEO error: ' . $response->get_error_message()); return false; } $code = wp_remote_retrieve_response_code($response); $body = json_decode(wp_remote_retrieve_body($response), true); if ($code !== 200) { error_log('Auto SEO HTTP ' . $code . ': ' . wp_remote_retrieve_body($response)); return false; } $text = $body['choices'][0]['message']['content'] ?? ''; if (empty($text)) return false; $text = preg_replace('/^```json\s*|\s*```$/m', '', trim($text)); $seo = json_decode($text, true); if (!isset($seo['title']) || !isset($seo['description'])) return false; return [ 'title' => mb_substr($seo['title'], 0, 60), 'description' => mb_substr($seo['description'], 0, 155), ]; } add_action('add_meta_boxes', function() { add_meta_box('auto_seo', 'Auto SEO', 'auto_seo_metabox', ['post', 'page'], 'side'); }); function auto_seo_metabox($post) { $keys = auto_seo_meta_keys(); $t = get_post_meta($post->ID, $keys['title'], true); $d = get_post_meta($post->ID, $keys['desc'], true); echo '

Title:
' . esc_html($t ?: '—') . '

'; echo '

Description:
' . esc_html($d ?: '—') . '

'; $url = wp_nonce_url(admin_url('admin-post.php?action=auto_seo_regen&post_id=' . $post->ID), 'auto_seo_' . $post->ID); echo '

Regenerate

'; } add_action('admin_post_auto_seo_regen', function() { $post_id = intval($_GET['post_id'] ?? 0); if (!current_user_can('edit_post', $post_id)) wp_die('No permission'); check_admin_referer('auto_seo_' . $post_id); $keys = auto_seo_meta_keys(); delete_post_meta($post_id, $keys['title']); delete_post_meta($post_id, $keys['desc']); auto_seo_on_save($post_id, get_post($post_id), true); wp_redirect(get_edit_post_link($post_id, 'raw')); exit; }); } // end function_exists guard